package com.example.android.fragments

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.android.R
import com.example.android.adapters.OnlineChatMessageViewAdapter
import com.example.android.extensions.AlertBar
import com.example.android.extensions.Services
import com.example.android.models.Message
import com.example.android.models.MessageView
import com.example.android.models.ToMessageView
import com.example.android.models.ToMessages
import com.example.android.utils.models.MyResult
import com.example.android.utils.websocket.IMyWebSocketPipeline
import com.example.android.utils.websocket.MyWebSocket
import com.example.android.viewmodels.OnlineChatViewModel
import com.example.android.viewmodels.SharedViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.time.Instant
import java.util.*
import kotlin.concurrent.thread

/**
 * @ClassName OnlineChatFragment
 * @Author Ryan Kamanri
 * @Date 2022/6/8
 * @Description
 **/

class OnlineChatFragment : Fragment(), IMyWebSocketPipeline {

    private var btn: Button? = null
    private lateinit var _MessageView: RecyclerView
    private val _Model: OnlineChatViewModel by activityViewModels()
    private val _SharedViewModel: SharedViewModel by activityViewModels()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_online_chat, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        _MessageView = view.findViewById(R.id.messages_recycler_view)

        btn = view.findViewById(R.id.send_button)

        val adapter = OnlineChatMessageViewAdapter(context!!, _Model.MessageViewItems)
        _MessageView.adapter = adapter
        _MessageView.layoutManager = LinearLayoutManager(context!!)

        val editText = view.findViewById<EditText>(R.id.editmsg)

        val selfId = _SharedViewModel.getSelf().value!!.id!!.toLong()

        var receiveUserId = 0L

        lifecycleScope.launch {
            val chatterIdResult = Services.OnlineChatService.GetChatterId(
                _SharedViewModel.getSelf().value!!.userName!!
            )
            when (chatterIdResult.Code) {
                MyResult.OK -> {
                    receiveUserId = (chatterIdResult.Data?.get("id") as Int).toLong()
                    Log.d(toString(), "Get Chat Id: $receiveUserId")
                }
                else -> {
                    Log.e(toString(), chatterIdResult.Message)
                }
            }
        }
        lifecycleScope.launch(Dispatchers.IO) {
            for (message in Services.MessageViewDao.SelectAll()) {
                _Model.MessageViewItems.add(message)
            }
        }


        btn?.setOnClickListener {
            val sendMessageText = editText.text
            val sendMessage = Message(
                id = 0,
                sendUserId = selfId,
                receiveUserId = receiveUserId,
                time = Date.from(Instant.now()),
                contentType = Message.Text,
                content = sendMessageText.toString()
            )
            Services.WebSocket.SendMessages(
                arrayListOf(
                    MyWebSocket.WebSocketMessage(
                        MyWebSocket.WebSocketMessageEvent.OnClientMessage,
                        MyWebSocket.WebSocketMessageType.Text,
                        Services.JsonUtil.ToJson(sendMessage)
                    )
                )
            )
            lifecycleScope.launch(Dispatchers.IO) {
                if (_Model.MessageViewItems.isEmpty() ||
                    sendMessage.time.minutes - _Model.MessageViewItems.last().time.minutes > 1
                ) {
                    val timeMessageView = sendMessage.ToMessageView(MessageView.ViewType.DATETIME)
                    _Model.MessageViewItems.add(timeMessageView)
                    Services.MessageViewDao.Insert(timeMessageView)
                }
                val messageView = sendMessage.ToMessageView(
                    when (sendMessage.contentType) {
                        Message.Text -> MessageView.ViewType.SELF_TEXT
                        else -> MessageView.ViewType.SELF_IMAGE
                    }
                )
                withContext(Dispatchers.Main) {
                    _Model.MessageViewItems.add(messageView)
                    _MessageView.adapter!!.notifyDataSetChanged()
                }

                Services.MessageViewDao.Insert(messageView)
            }


            _MessageView.adapter?.notifyDataSetChanged()
            Log.i(toString(), "Send A Message")
            editText.text.clear()

        }

        thread {
            while (true) {
                Thread.sleep(3000)
                requireActivity().runOnUiThread {
                    _MessageView.adapter?.notifyDataSetChanged()
                }
            }
        }


    }

    override fun MyWebSocketExecutor(myWebSocket: MyWebSocket) {

        /**
         * 接受服务端临时保存的消息
         */
        myWebSocket.AddEventHandler(MyWebSocket.WebSocketMessageEvent.OnServerTempMessage) {
            val messages = it.ToMessages()

            if (_Model.UserId_MessageViewList_Pairs[messages[0].sendUserId] == null)
                _Model.UserId_MessageViewList_Pairs[messages[0].sendUserId] = arrayListOf()

            val messageViewItems = _Model.UserId_MessageViewList_Pairs[messages[0].sendUserId]!!

            for (message in messages) {
                if (messageViewItems.isEmpty() || message.time.minutes - messageViewItems.last().time.minutes > 1) {
                    val timeMessageView = message.ToMessageView(MessageView.ViewType.DATETIME)
                    messageViewItems.add(timeMessageView)
                    Services.MessageViewDao.Insert(timeMessageView)
                }
                val messageView = message.ToMessageView(
                    when (message.contentType) {
                        Message.Text -> MessageView.ViewType.OTHER_TEXT
                        else -> MessageView.ViewType.OTHER_IMAGE
                    }
                )
                messageViewItems.add(messageView)
                lifecycleScope.launch(Dispatchers.IO) {
                    Services.MessageViewDao.Insert(messageView)
                }
            }
            requireActivity().runOnUiThread {
                _MessageView.adapter?.notifyDataSetChanged()
            }

            Log.i(
                toString(),
                "Receive ${it.size} Temporary Message From ${messages[0].sendUserId}, Message Count : ${messageViewItems.size}"
            )
            return@AddEventHandler arrayListOf()
        }

        /**
         * 接收服务端正在发送的消息
         */
        myWebSocket.AddEventHandler(MyWebSocket.WebSocketMessageEvent.OnServerMessage) {
            val messages = it.ToMessages()

            if (_Model.UserId_MessageViewList_Pairs[messages[0].sendUserId] == null)
                _Model.UserId_MessageViewList_Pairs[messages[0].sendUserId] = arrayListOf()

            val messageViewItems = _Model.UserId_MessageViewList_Pairs[messages[0].sendUserId]!!

            for (message in messages) {
                if (messageViewItems.isEmpty() || message.time.minutes - messageViewItems.last().time.minutes > 1) {
                    val timeMessageView = message.ToMessageView(MessageView.ViewType.DATETIME)
                    messageViewItems.add(timeMessageView)
                    lifecycleScope.launch(Dispatchers.IO) {
                        Services.MessageViewDao.Insert(timeMessageView)
                    }

                }
                val messageView = message.ToMessageView(
                    when (message.contentType) {
                        Message.Text -> MessageView.ViewType.OTHER_TEXT
                        else -> MessageView.ViewType.OTHER_IMAGE
                    }
                )
                messageViewItems.add(messageView)
                lifecycleScope.launch(Dispatchers.IO) {
                    Services.MessageViewDao.Insert(messageView)
                }
            }
            requireActivity().runOnUiThread {
                _MessageView.adapter!!.notifyDataSetChanged()
            }

            AlertBar {
                it.setIcon(R.drawable.ic_baseline_chat_24)
                    .setTitle(R.string.menu_online_chat)
                    .setText(
                        "对接学长: ${
                            when (messages[0].contentType) {
                                Message.Text -> messages[0].content as String
                                else -> "[图片]"
                            }
                        }"
                    )
            }

            Log.i(
                toString(),
                "Receive ${it.size} Message From ${messages[0].sendUserId}, Message Count : ${messageViewItems.size}"
            )
            return@AddEventHandler arrayListOf()
        }
    }
}